<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>创建批量推理任务</title>
<script src="https://cdn.tailwindcss.com/3.4.16"></script>
<link href="https://cdnjs.cloudflare.com/ajax/libs/remixicon/4.6.0/remixicon.min.css" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#3B82F6',
secondary: '#6B7280'
},
borderRadius: {
'none': '0px',
'sm': '4px',
DEFAULT: '8px',
'md': '12px',
'lg': '16px',
'xl': '20px',
'2xl': '24px',
'3xl': '32px',
'full': '9999px',
'button': '8px'
}
}
}
}
</script>
<style>
:where([class^="ri-"])::before { content: "\f3c2"; }
.custom-scrollbar::-webkit-scrollbar { width: 4px; }
.custom-scrollbar::-webkit-scrollbar-track { background: transparent; }
.custom-scrollbar::-webkit-scrollbar-thumb { background: #E5E7EB; border-radius: 4px; }
.custom-range::-webkit-slider-thumb {
appearance: none;
width: 20px;
height: 20px;
border-radius: 50%;
background: #3B82F6;
cursor: pointer;
border: 2px solid white;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.custom-range::-webkit-slider-track {
width: 100%;
height: 4px;
cursor: pointer;
background: #E5E7EB;
border-radius: 2px;
}
.custom-checkbox {
appearance: none;
width: 20px;
height: 20px;
border: 2px solid #D1D5DB;
border-radius: 4px;
background: white;
cursor: pointer;
position: relative;
}
.custom-checkbox:checked {
background: #3B82F6;
border-color: #3B82F6;
}
.custom-checkbox:checked::after {
content: '✓';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: white;
font-size: 12px;
font-weight: bold;
}
.custom-radio {
appearance: none;
width: 20px;
height: 20px;
border: 2px solid #D1D5DB;
border-radius: 50%;
background: white;
cursor: pointer;
position: relative;
}
.custom-radio:checked {
border-color: #3B82F6;
}
.custom-radio:checked::after {
content: '';
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 8px;
height: 8px;
border-radius: 50%;
background: #3B82F6;
}
.custom-switch {
appearance: none;
width: 44px;
height: 24px;
background: #E5E7EB;
border-radius: 12px;
position: relative;
cursor: pointer;
transition: background 0.3s;
}
.custom-switch:checked {
background: #3B82F6;
}
.custom-switch::after {
content: '';
position: absolute;
top: 2px;
left: 2px;
width: 20px;
height: 20px;
background: white;
border-radius: 50%;
transition: transform 0.3s;
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
}
.custom-switch:checked::after {
transform: translateX(20px);
}
.file-upload-area {
border: 2px dashed #D1D5DB;
transition: all 0.3s;
}
.file-upload-area:hover {
border-color: #3B82F6;
background: #F8FAFF;
}
.file-upload-area.dragover {
border-color: #3B82F6;
background: #F0F7FF;
}
</style>
</head>
<body class="bg-gray-50">
<div class="flex h-screen">
<aside class="w-64 bg-white border-r border-gray-200 flex flex-col">
<div class="p-4 border-b border-gray-200">
<div class="flex items-center">
<a href="#" class="text-2xl font-['Pacifico'] text-primary">logo</a>
</div>
</div>
<nav class="flex-1 overflow-y-auto custom-scrollbar">
<div class="p-2 space-y-1">
<div class="group">
<div class="flex items-center px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-button">
<div class="w-4 h-4 flex items-center justify-center mr-2">
<i class="ri-dashboard-line"></i>
</div>
<span>模型管理</span>
<i class="ri-arrow-down-s-line ml-auto"></i>
</div>
<div class="ml-6 mt-1 space-y-1">
<div class="flex items-center px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-button">
<span>模型生命周期</span>
</div>
<div class="flex items-center px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-button">
<span>模型运行统计</span>
</div>
<div class="flex items-center px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-button">
<span>模型预测结果</span>
</div>
</div>
</div>
<div class="group">
<div class="flex items-center px-3 py-2 text-sm text-primary bg-blue-50 rounded-button">
<div class="w-4 h-4 flex items-center justify-center mr-2">
<i class="ri-settings-line"></i>
</div>
<span>推理服务</span>
</div>
</div>
<div class="group">
<div class="flex items-center px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-button">
<div class="w-4 h-4 flex items-center justify-center mr-2">
<i class="ri-api-line"></i>
</div>
<span>API 接口</span>
<i class="ri-arrow-down-s-line ml-auto"></i>
</div>
</div>
<div class="group">
<div class="flex items-center px-3 py-2 text-sm text-gray-600 hover:bg-gray-50 rounded-button">
<div class="w-4 h-4 flex items-center justify-center mr-2">
<i class="ri-database-2-line"></i>
</div>
<span>数据处理</span>
<i class="ri-arrow-down-s-line ml-auto"></i>
</div>
</div>
</div>
</nav>
</aside>
<main class="flex-1 flex flex-col overflow-hidden">
<header class="h-16 bg-white border-b border-gray-200 flex items-center justify-between px-6">
<h1 class="text-lg font-medium">创建批量推理任务</h1>
<div class="flex items-center space-x-4">
<a href="https://readdy.ai/home/42b69b4b-e314-4f8d-9e2f-98a4952face1/83af26fe-6a2c-4b4d-9dc6-9dd0ca282c18" data-readdy="true">
<button class="flex items-center px-4 py-2 bg-gray-100 text-gray-700 rounded-button hover:bg-gray-200 transition-colors whitespace-nowrap">
<i class="ri-arrow-left-line mr-1"></i>
返回
</button>
</a>
<div class="w-8 h-8 rounded-full bg-gray-200 flex items-center justify-center">
<i class="ri-user-line text-gray-600"></i>
</div>
</div>
</header>
<div class="flex-1 overflow-auto p-6">
<div class="max-w-4xl mx-auto space-y-6">
<div class="bg-white rounded-xl p-6 shadow-sm">
<h2 class="text-lg font-medium mb-4 flex items-center">
<div class="w-6 h-6 flex items-center justify-center mr-2">
<i class="ri-file-text-line text-primary"></i>
</div>
任务基本信息
</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
任务名称 <span class="text-red-500">*</span>
</label>
<input type="text" placeholder="请输入任务名称" class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">任务描述</label>
<textarea placeholder="请输入任务描述（选填）" rows="3" class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm resize-none"></textarea>
</div>
</div>
</div>
<div class="bg-white rounded-xl p-6 shadow-sm">
<h2 class="text-lg font-medium mb-4 flex items-center">
<div class="w-6 h-6 flex items-center justify-center mr-2">
<i class="ri-cpu-line text-primary"></i>
</div>
模型选择
</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">
选择模型 <span class="text-red-500">*</span>
</label>
<div class="relative">
<select class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm appearance-none pr-8">
<option value="">请选择模型</option>
<option value="bert-base">BERT Base v1.2.3</option>
<option value="gpt-3.5">GPT-3.5 Turbo v2.1.0</option>
<option value="resnet-50">ResNet-50 v1.8.2</option>
<option value="yolo-v8">YOLO v8.0.1</option>
</select>
<div class="absolute right-3 top-3.5 w-4 h-4 flex items-center justify-center pointer-events-none">
<i class="ri-arrow-down-s-line text-gray-400"></i>
</div>
</div>
</div>
<div class="bg-gray-50 rounded-lg p-4">
<div class="flex items-center justify-between text-sm">
<span class="text-gray-600">模型版本：</span>
<span class="font-medium">v1.2.3</span>
</div>
<div class="flex items-center justify-between text-sm mt-2">
<span class="text-gray-600">模型类型：</span>
<span class="font-medium">自然语言处理</span>
</div>
<div class="flex items-center justify-between text-sm mt-2">
<span class="text-gray-600">支持格式：</span>
<span class="font-medium">JSON, CSV, TXT</span>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-xl p-6 shadow-sm">
<h2 class="text-lg font-medium mb-4 flex items-center">
<div class="w-6 h-6 flex items-center justify-center mr-2">
<i class="ri-database-2-line text-primary"></i>
</div>
数据源配置
</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-3">
数据来源 <span class="text-red-500">*</span>
</label>
<div class="flex bg-gray-100 rounded-lg p-1">
<button class="data-source-tab flex-1 px-4 py-2 text-sm font-medium rounded-md bg-white text-primary shadow-sm" data-tab="upload">
文件上传
</button>
<button class="data-source-tab flex-1 px-4 py-2 text-sm font-medium rounded-md text-gray-600 hover:text-gray-900" data-tab="dataset">
选择数据集
</button>
</div>
</div>
<div id="upload-section" class="data-section">
<div class="file-upload-area rounded-lg p-8 text-center cursor-pointer">
<div class="w-12 h-12 flex items-center justify-center mx-auto mb-4">
<i class="ri-upload-cloud-2-line text-3xl text-gray-400"></i>
</div>
<p class="text-gray-600 mb-2">点击上传或拖拽文件到此区域</p>
<p class="text-sm text-gray-400">支持 JSON、CSV、TXT 格式，最大 100MB</p>
<input type="file" class="hidden" accept=".json,.csv,.txt" multiple>
</div>
<div class="uploaded-files mt-4 space-y-2 hidden">
<div class="flex items-center justify-between p-3 bg-gray-50 rounded-lg">
<div class="flex items-center">
<div class="w-8 h-8 flex items-center justify-center mr-3">
<i class="ri-file-text-line text-gray-600"></i>
</div>
<div>
<div class="text-sm font-medium">sample_data.csv</div>
<div class="text-xs text-gray-500">2.5 MB</div>
</div>
</div>
<button class="w-6 h-6 flex items-center justify-center text-gray-400 hover:text-red-500">
<i class="ri-close-line"></i>
</button>
</div>
</div>
</div>
<div id="dataset-section" class="data-section hidden">
<div class="space-y-3">
<div class="border border-gray-200 rounded-lg p-4 cursor-pointer hover:border-primary hover:bg-blue-50">
<div class="flex items-center">
<input type="radio" name="dataset" value="dataset1" class="custom-radio mr-3">
<div class="flex-1">
<div class="font-medium text-sm">客户评论数据集</div>
<div class="text-xs text-gray-500 mt-1">包含 50,000 条客户评论数据，已预处理</div>
<div class="text-xs text-gray-400 mt-1">更新时间：2024-12-15</div>
</div>
</div>
</div>
<div class="border border-gray-200 rounded-lg p-4 cursor-pointer hover:border-primary hover:bg-blue-50">
<div class="flex items-center">
<input type="radio" name="dataset" value="dataset2" class="custom-radio mr-3">
<div class="flex-1">
<div class="font-medium text-sm">产品图像数据集</div>
<div class="text-xs text-gray-500 mt-1">包含 25,000 张产品图像，分类标注完整</div>
<div class="text-xs text-gray-400 mt-1">更新时间：2024-12-10</div>
</div>
</div>
</div>
<div class="border border-gray-200 rounded-lg p-4 cursor-pointer hover:border-primary hover:bg-blue-50">
<div class="flex items-center">
<input type="radio" name="dataset" value="dataset3" class="custom-radio mr-3">
<div class="flex-1">
<div class="font-medium text-sm">用户行为数据集</div>
<div class="text-xs text-gray-500 mt-1">包含用户点击、浏览、购买等行为数据</div>
<div class="text-xs text-gray-400 mt-1">更新时间：2024-12-08</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-xl p-6 shadow-sm">
<h2 class="text-lg font-medium mb-4 flex items-center">
<div class="w-6 h-6 flex items-center justify-center mr-2">
<i class="ri-file-download-line text-primary"></i>
</div>
输出设置
</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">输出格式</label>
<div class="flex bg-gray-100 rounded-lg p-1">
<button class="output-format-tab flex-1 px-4 py-2 text-sm font-medium rounded-md bg-white text-primary shadow-sm" data-format="json">
JSON
</button>
<button class="output-format-tab flex-1 px-4 py-2 text-sm font-medium rounded-md text-gray-600 hover:text-gray-900" data-format="csv">
CSV
</button>
<button class="output-format-tab flex-1 px-4 py-2 text-sm font-medium rounded-md text-gray-600 hover:text-gray-900" data-format="txt">
TXT
</button>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">输出路径</label>
<input type="text" placeholder="/output/batch_inference_results" class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
<div>
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-3">
<span class="text-sm text-gray-700">任务完成后发送邮件通知</span>
</label>
</div>
<div>
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-3">
<span class="text-sm text-gray-700">保存中间结果</span>
</label>
</div>
</div>
</div>
<div class="bg-white rounded-xl p-6 shadow-sm">
<h2 class="text-lg font-medium mb-4 flex items-center">
<div class="w-6 h-6 flex items-center justify-center mr-2">
<i class="ri-server-line text-primary"></i>
</div>
资源配置
</h2>
<div class="space-y-6">
<div>
<label class="block text-sm font-medium text-gray-700 mb-3">计算资源类型</label>
<div class="grid grid-cols-2 gap-4">
<div class="border border-gray-200 rounded-lg p-4 cursor-pointer hover:border-primary hover:bg-blue-50 resource-option" data-resource="cpu">
<div class="flex items-center mb-2">
<input type="radio" name="resource" value="cpu" class="custom-radio mr-3">
<div class="w-8 h-8 flex items-center justify-center mr-2">
<i class="ri-cpu-line text-blue-600"></i>
</div>
<span class="font-medium text-sm">CPU</span>
</div>
<div class="text-xs text-gray-500">适合轻量级推理任务</div>
<div class="text-xs text-gray-600 mt-1">4 核 8GB 内存</div>
</div>
<div class="border border-gray-200 rounded-lg p-4 cursor-pointer hover:border-primary hover:bg-blue-50 resource-option" data-resource="gpu">
<div class="flex items-center mb-2">
<input type="radio" name="resource" value="gpu" class="custom-radio mr-3">
<div class="w-8 h-8 flex items-center justify-center mr-2">
<i class="ri-computer-line text-green-600"></i>
</div>
<span class="font-medium text-sm">GPU</span>
</div>
<div class="text-xs text-gray-500">适合深度学习推理任务</div>
<div class="text-xs text-gray-600 mt-1">NVIDIA T4 16GB 显存</div>
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-3">并发数设置</label>
<div class="flex items-center space-x-4">
<span class="text-sm text-gray-600">1</span>
<input type="range" min="1" max="32" value="8" class="flex-1 custom-range" id="concurrency-slider">
<span class="text-sm text-gray-600">32</span>
<div class="w-16 text-center">
<span class="text-sm font-medium" id="concurrency-value">8</span>
</div>
</div>
<div class="mt-2 text-xs text-gray-500">当前设置：8 个并发任务</div>
</div>
<div class="bg-gray-50 rounded-lg p-4">
<div class="text-sm font-medium text-gray-700 mb-2">预估资源消耗</div>
<div class="space-y-2 text-sm">
<div class="flex justify-between">
<span class="text-gray-600">计算时长：</span>
<span>约 2.5 小时</span>
</div>
<div class="flex justify-between">
<span class="text-gray-600">资源费用：</span>
<span class="text-primary font-medium">¥ 45.80</span>
</div>
</div>
</div>
</div>
</div>
<div class="bg-white rounded-xl p-6 shadow-sm">
<h2 class="text-lg font-medium mb-4 flex items-center">
<div class="w-6 h-6 flex items-center justify-center mr-2">
<i class="ri-time-line text-primary"></i>
</div>
任务调度设置
</h2>
<div class="space-y-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-3">执行时间</label>
<div class="flex bg-gray-100 rounded-lg p-1">
<button class="schedule-tab flex-1 px-4 py-2 text-sm font-medium rounded-md bg-white text-primary shadow-sm" data-schedule="immediate">
立即执行
</button>
<button class="schedule-tab flex-1 px-4 py-2 text-sm font-medium rounded-md text-gray-600 hover:text-gray-900" data-schedule="scheduled">
定时执行
</button>
</div>
</div>
<div id="scheduled-section" class="hidden space-y-4">
<div class="grid grid-cols-2 gap-4">
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">执行日期</label>
<input type="date" class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-2">执行时间</label>
<input type="time" class="w-full px-4 py-3 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
</div>
</div>
</div>
<div>
<label class="block text-sm font-medium text-gray-700 mb-3">重试策略</label>
<div class="space-y-3">
<label class="flex items-center">
<input type="checkbox" class="custom-checkbox mr-3" checked>
<span class="text-sm text-gray-700">启用自动重试</span>
</label>
<div class="ml-6 space-y-3">
<div>
<label class="block text-sm text-gray-600 mb-2">最大重试次数</label>
<select class="w-32 px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
<option value="1">1 次</option>
<option value="2" selected>2 次</option>
<option value="3">3 次</option>
<option value="5">5 次</option>
</select>
</div>
<div>
<label class="block text-sm text-gray-600 mb-2">重试间隔</label>
<select class="w-32 px-3 py-2 border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent text-sm">
<option value="30">30 秒</option>
<option value="60" selected>1 分钟</option>
<option value="300">5 分钟</option>
<option value="600">10 分钟</option>
</select>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="fixed bottom-0 left-64 right-0 bg-white border-t border-gray-200 px-6 py-4">
<div class="flex items-center justify-between max-w-4xl mx-auto">
<a href="https://readdy.ai/home/42b69b4b-e314-4f8d-9e2f-98a4952face1/83af26fe-6a2c-4b4d-9dc6-9dd0ca282c18" data-readdy="true">
<button class="px-6 py-3 border border-gray-300 text-gray-700 rounded-button hover:bg-gray-50 transition-colors whitespace-nowrap">
取消
</button>
</a>
<div class="flex items-center space-x-4">
<button class="px-6 py-3 border border-gray-300 text-gray-700 rounded-button hover:bg-gray-50 transition-colors whitespace-nowrap">
保存草稿
</button>
<button class="px-6 py-3 bg-primary text-white rounded-button hover:bg-blue-600 transition-colors whitespace-nowrap">
创建任务
</button>
</div>
</div>
</div>
</main>
</div>
<script id="tab-switching">
document.addEventListener('DOMContentLoaded', function() {
const dataSourceTabs = document.querySelectorAll('.data-source-tab');
const dataSections = document.querySelectorAll('.data-section');
dataSourceTabs.forEach(tab => {
tab.addEventListener('click', function() {
const targetTab = this.dataset.tab;
dataSourceTabs.forEach(t => {
t.classList.remove('bg-white', 'text-primary', 'shadow-sm');
t.classList.add('text-gray-600');
});
this.classList.add('bg-white', 'text-primary', 'shadow-sm');
this.classList.remove('text-gray-600');
dataSections.forEach(section => {
section.classList.add('hidden');
});
document.getElementById(targetTab + '-section').classList.remove('hidden');
});
});
const outputFormatTabs = document.querySelectorAll('.output-format-tab');
outputFormatTabs.forEach(tab => {
tab.addEventListener('click', function() {
outputFormatTabs.forEach(t => {
t.classList.remove('bg-white', 'text-primary', 'shadow-sm');
t.classList.add('text-gray-600');
});
this.classList.add('bg-white', 'text-primary', 'shadow-sm');
this.classList.remove('text-gray-600');
});
});
const scheduleTabs = document.querySelectorAll('.schedule-tab');
const scheduledSection = document.getElementById('scheduled-section');
scheduleTabs.forEach(tab => {
tab.addEventListener('click', function() {
const targetSchedule = this.dataset.schedule;
scheduleTabs.forEach(t => {
t.classList.remove('bg-white', 'text-primary', 'shadow-sm');
t.classList.add('text-gray-600');
});
this.classList.add('bg-white', 'text-primary', 'shadow-sm');
this.classList.remove('text-gray-600');
if (targetSchedule === 'scheduled') {
scheduledSection.classList.remove('hidden');
} else {
scheduledSection.classList.add('hidden');
}
});
});
});
</script>
<script id="file-upload">
document.addEventListener('DOMContentLoaded', function() {
const fileUploadArea = document.querySelector('.file-upload-area');
const fileInput = fileUploadArea.querySelector('input[type="file"]');
const uploadedFilesContainer = document.querySelector('.uploaded-files');
fileUploadArea.addEventListener('click', function() {
fileInput.click();
});
fileUploadArea.addEventListener('dragover', function(e) {
e.preventDefault();
this.classList.add('dragover');
});
fileUploadArea.addEventListener('dragleave', function() {
this.classList.remove('dragover');
});
fileUploadArea.addEventListener('drop', function(e) {
e.preventDefault();
this.classList.remove('dragover');
const files = e.dataTransfer.files;
handleFiles(files);
});
fileInput.addEventListener('change', function() {
handleFiles(this.files);
});
function handleFiles(files) {
if (files.length > 0) {
uploadedFilesContainer.classList.remove('hidden');
}
}
});
</script>
<script id="range-slider">
document.addEventListener('DOMContentLoaded', function() {
const concurrencySlider = document.getElementById('concurrency-slider');
const concurrencyValue = document.getElementById('concurrency-value');
concurrencySlider.addEventListener('input', function() {
concurrencyValue.textContent = this.value;
});
});
</script>
<script id="resource-selection">
document.addEventListener('DOMContentLoaded', function() {
const resourceOptions = document.querySelectorAll('.resource-option');
resourceOptions.forEach(option => {
option.addEventListener('click', function() {
const radio = this.querySelector('input[type="radio"]');
radio.checked = true;
});
});
});
</script>
</body>
</html>